#ifndef NJF_RASTER_H
#define NJF_RASTER_H

#include <stdint.h>
#include "raster-fixed.h"

/* represents a single X8R8G8B8 or A8R8G8B8 pixel */
typedef uint32_t Pixel;
#define PIXEL_TARGET_ALPHA_MASK 0xFF000000

/* converts individual color channels into a usable color value */
#define Pixel_RGB(r, g, b) ((Pixel)(0xFF000000|(((r)&0xFF) << 16)|(((g)&0xFF) << 8)|((b)&0xFF)))
#define Pixel_RGBA(r, g, b, a) ((Pixel)((((a)&0xFF) << 24)|(((r)&0xFF) << 16)|(((g)&0xFF) << 8)|((b)&0xFF)))

typedef struct
{
    int x;
    int y;
    int w;
    int h;
} RasterRect;

/* Holds all necessary data for basic raster graphics */
typedef struct
{
    unsigned int fmt;
    unsigned int width;
    unsigned int height;
    unsigned int pitch; /* must be >= width */
    RasterRect clipRect;
    Pixel *pixels;
    void *rasterTargetData;
} Raster;

typedef struct
{
    int x;
    int y;
} RasterPos;

typedef struct
{
    Fixed u;
    Fixed v;
} RasterPosUV;

#define ERROR_INVALID_INPUT -1

/*
    Allocates and initializes a new raster with the specified format, width, and height.
*/
EXTERNC Raster * __cdecl CreateRaster(unsigned int fmt, unsigned int width, unsigned int height);
/*
    Frees all memory used by a raster created with CreateRaster or RasterFromFile
*/
EXTERNC void __cdecl DestroyRaster(Raster *raster);

BEST_INLINE void RasterSetClipRect(Raster *raster, const RasterRect *rect)
{
    if(!rect)
    {
        raster->clipRect.x = raster->clipRect.y = 0;
        raster->clipRect.w = raster->width;
        raster->clipRect.h = raster->height;
    }
    else if(rect->x >= 0 && rect->y >= 0 && rect->w > 0 && rect->h > 0 &&
            (rect->x + rect->w) <= raster->width && (rect->y + rect->h) <= raster->height)
    {
        raster->clipRect.x = rect->x;
        raster->clipRect.y = rect->y;
        raster->clipRect.w = rect->w;
        raster->clipRect.h = rect->h;
    }
}

/*
    Fills a rectangular region of a raster with a single color
*/
EXTERNC int __cdecl RasterFillRect(Raster *raster, Pixel color, const RasterRect *pRect);
/*
    Sets the entire contents of a raster to a single color.
*/
EXTERNC int __cdecl RasterClear(Raster *raster, Pixel color);
/*
    Draws a line between the specified points on the raster
*/
EXTERNC int __cdecl RasterDrawLine(Raster *raster, Pixel color, const RasterPos *pt1, const RasterPos *pt2);

/*
    Draws a solid color triangle without arranged vertices
*/
EXTERNC int __cdecl RasterDrawTriangle(Raster *raster, Pixel color, const RasterPos *pts);

/* default blitting mode, with alpha channel if available */
#define BLIT_NORMAL 0
/* ignore alpha channel during blitting */
#define BLIT_OPAQUE 1
/* specify a color to represent full transparency */
#define BLIT_COLORKEY 2
/* blit with each color channel as a range between channels of two other colors
    includes BLIT_ALPHAMOD functionality
 */
#define BLIT_COLORMOD 4
/* blit with each pixel having an alpha adjusted to be in a specified range
    cannot be mixed with BLIT_OPAQUE or BLIT_COLORMOD
 */
#define BLIT_ALPHAMOD 8
/* interpolation */
#define BLIT_INTERPOLATE_NEAREST     0 /* choose the nearest pixel */
#define BLIT_INTERPOLATE_BILINEAR    1 /* interpolate between bordering pixels */
typedef struct
{
    unsigned int modes; /* or mask of modes */
    int interpolation;
    /* 0 for affine, 1 for true perspective correction, >1 sets step for sub-affine correction */
    int perspective_correction;
    /* BLIT_COLORKEY */
    Pixel colorkey;
    union
    {
        /* BLIT_COLORMOD */
        struct
        {
            Pixel wht;
            Pixel blk;
        } color;
        /* BLIT_ALPHAMOD */
        struct
        {
            unsigned char high;
            unsigned char low;
        } alpha;
    } mod;

} BlitMode;

/*
    blits a rectangular region from src into dest based on optionally specified mode
*/
EXTERNC int RasterBlit(Raster *dest, const RasterPos *pos, Raster *src, const RasterRect *srcRect, BlitMode *mode);

/*
    blits a rectangular region from src into a rectangular region of dest
*/
EXTERNC int RasterStretchBlit(Raster *dest, const RasterRect *destRect, Raster *src, const RasterRect *srcRect, BlitMode *mode);

/*
    blits a triangular region from src into a triangular region of dest
*/
EXTERNC int RasterTriangleBlit(Raster *dest, const RasterPos *destPts, Raster *src, const RasterPos *srcPts, BlitMode *mode);

EXTERNC int RasterQuadBlit(Raster *dest, const RasterPos *destPts, Raster *src, const RasterPos *srcPts, BlitMode *mode);

#include "raster-formats.h"

#endif /* NJF_RASTER_H */
